﻿/*
 * Erstellt mit SharpDevelop.
 * Benutzer: Kai Patrick
 * Datum: 17.03.2008
 * Zeit: 19:41
 * 
 * Sie können diese Vorlage unter Extras > Optionen > Codeerstellung > Standardheader ändern.
 */

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

namespace Gamadus.Designer
{
	/// <summary>
	/// Description of EditObjectForm.
	/// </summary>
	public partial class EditObjectForm : Form, IEditWindow
	{
		Gamadus.Designer.Object res;
		Dictionary<ListViewItem, Event> eventList = new Dictionary<ListViewItem, Event>();
		public Dictionary<ListViewItem, Event> EventList
		{
			get
			{
				return eventList;
			}
		}
		Dictionary<ListViewItem, Action> actionList = new Dictionary<ListViewItem, Action>();
		Dictionary<ListViewItem, ActionPrototype> actionPrototypes = new Dictionary<ListViewItem, ActionPrototype>();
		
		public EditObjectForm(Gamadus.Designer.Object res)
		{
			this.res = res;
			
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			listViewEvents.Columns[0].Width = -2;
			listViewActions.Columns[0].Width = -2;
			listViewEvents.Sorting = SortOrder.Ascending;
			listViewEvents.ListViewItemSorter = new ListViewEventSorter(this);
			
			this.MdiParent = ResourceMgr.Instance.MainForm;
			this.Show();
			
			foreach(ActionSet aset in ActionSetMgr.Instance.ActionSets)
			{
				TabPage page = new TabPage(aset.Name);
				ListView list = new ListView();
				
				list.Dock = DockStyle.Fill;
				list.View = View.Tile;
				list.TileSize = new Size(30,30);
				list.ShowItemToolTips = true;
				list.MultiSelect = false;
				list.BorderStyle = BorderStyle.None;
				list.LargeImageList = imageListActions;
				list.BackColor = SystemColors.Control;
				list.ItemDrag += new ItemDragEventHandler(ListViewActionSetItemDrag); 
				list.HeaderStyle = ColumnHeaderStyle.Nonclickable;
				
				Dictionary<string, ListViewGroup> groupList = new Dictionary<string, ListViewGroup>();
				foreach(string grpName in aset.Groups)
				{
					ListViewGroup grp = new ListViewGroup(grpName);
					list.Groups.Add(grp);
					groupList.Add(grpName, grp);
				}
				
				foreach(ActionPrototype action in aset.Actions)
				{
					ListViewItem item = new ListViewItem(action.Name);
					item.ImageKey = action.ImageKey;
					item.Group = groupList[action.Group];
					item.ImageIndex = 0;
					item.ToolTipText = action.Name;
					list.Items.Add(item);
					actionPrototypes.Add(item, action);
				}
				
				page.Controls.Add(list);
				tabControlActions.TabPages.Add(page);
				
			}
			this.UpdateEditForm();
			
			#region Fill in the current values
			
			//Events
			foreach(Event evt in res.CloneEvents())
			{
				ListViewItem item = new ListViewItem(evt.Name, 0);
				listViewEvents.Items.Add(item);
				item.ImageKey = evt.Name;
				eventList.Add(item, evt);
			}
			
			checkBoxPersistent.Checked = (bool)res.Settings["persistent"];
			checkBoxVisible.Checked = (bool)res.Settings["visible"];
			checkBoxSolid.Checked = (bool)res.Settings["solid"];
			textBoxDepth.Text = ((int)res.Settings["depth"]).ToString();
			
			textBoxDepth.Validating += ResourceMgr.Instance.ValidateIntegerText;
			textBoxName.Validating += ResourceMgr.Instance.ValidateResourceNameText;
			#endregion
			
			//Select first event
			if(listViewEvents.Items.Count > 0)
			{
				listViewEvents.Items[0].Selected = true;
			}
			listViewEvents.Select();
		}
		
		public Resource Editing 
		{
			get
			{
				return res;
			}
		}
		
		public void UpdateEditForm()
		{
			textBoxName.Text = res.Name;
		}
		
		
		
		ListViewItem FindEvent(EventType type)
		{
			foreach(KeyValuePair<ListViewItem,Event> pair in eventList)
			{
				if(pair.Value.Type == type)
					return pair.Key;
			}
			return null;
		}
		
		void EditObjectFormResize(object sender, EventArgs e)
		{
			//auto resize action list view column
			listViewActions.Columns[0].Width = -2;
		}
		
		void ButtonEventAddClick(object sender, EventArgs e)
		{
			EventType selectedType = EventSelectorForm.ShowSelectorDialog();
			if(selectedType == EventType.None)
				return;
			
			ListViewItem item = FindEvent(selectedType);
			if(item == null)
			{
				Event evt = new Event(selectedType);
				item = new ListViewItem(evt.Name,0);
				item.ImageKey = evt.Name;
				eventList.Add(item, evt);
				listViewEvents.Items.Add(item);
			}
			item.Selected = true;
			listViewEvents.Select();
		}
		
		void ButtonOKClick(object sender, EventArgs e)
		{
			Close(false);
		}
		
		bool closeDontAsk = false;
		
		public void Close(bool askForSave)
		{
			closeDontAsk = !askForSave;
			this.Close();
		}
		
		void EditObjectFormFormClosing(object sender, FormClosingEventArgs e)
		{
			//check for unvalid text in validated textboxes (FIX for bug #3)
			if(!ResourceMgr.Instance.IsValidName(textBoxName.Text, res)  || 
			   !ResourceMgr.Instance.IsValidInteger(textBoxDepth.Text))
			{
				e.Cancel = true;
				return;
			}
			
			bool save = true;
			if(!closeDontAsk)
			{
				DialogResult result = MessageBox.Show("Save changes to "+res.Name+"?","Warning",
				                                      MessageBoxButtons.YesNoCancel,
				                                      MessageBoxIcon.Warning);
				if(result == DialogResult.Cancel)
				{
					e.Cancel = true;
					return;
				}
				if(result == DialogResult.No)
					save = false;
			}
			closeDontAsk = false;
			
			if(save)
			{
				res.SaveEvents(new List<Event>(eventList.Values));
				res.Settings["persistent"] = checkBoxPersistent.Checked;
				res.Settings["visible"] = checkBoxVisible.Checked;
				res.Settings["solid"] = checkBoxSolid.Checked;
				res.Settings["depth"] = int.Parse(textBoxDepth.Text);
				
				res.Name = textBoxName.Text;
			}
			res.CloseEditorHandle(save);
		}
		
		void ButtonEventDeleteClick(object sender, EventArgs e)
		{
			if(listViewEvents.SelectedItems.Count == 0)
				return;
			
			ListViewItem item = listViewEvents.SelectedItems[0];
		
			DialogResult result = MessageBox.Show("Are you sure you want to remove the "+eventList[item].Name+" event with all of its actions?",
			                                      "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			if(result == DialogResult.No)
				return;
			
			eventList.Remove(item);
			listViewEvents.Items.Remove(item);
		}
		
		void ButtonEventChangeClick(object sender, EventArgs e)
		{
			throw new NotImplementedException();
		}
		
		void ListViewActionsItemDrag(object sender, ItemDragEventArgs e)
		{
			//Begins a drag-and-drop operation in the ListView control.
			listViewActions.DoDragDrop(listViewActions.SelectedItems, DragDropEffects.Move);
		}
		
		void ListViewActionsDragEnter(object sender, DragEventArgs e)
		{
			foreach(string format in e.Data.GetFormats())
			{
				if(format.Equals("System.Windows.Forms.ListView+SelectedListViewItemCollection"))
				{
					e.Effect = DragDropEffects.Move;
				}
				else if(format.Equals("System.Windows.Forms.ListViewItem"))
				{
					e.Effect = DragDropEffects.Copy;
				}
			}
		}
		
		void ListViewActionsDragDrop(object sender, DragEventArgs e)
		{
			if(e.Data.GetFormats().Length > 1 && e.Data.GetFormats()[1].Equals("System.Windows.Forms.ListViewItem"))
			{
				if(listViewEvents.SelectedItems.Count == 0)
					return;
				ActionPrototype prototype = actionPrototypes[(ListViewItem)e.Data.GetData(typeof(ListViewItem))];
				Action action = new Action(prototype);
				
				ListViewItem item = new ListViewItem(action.Description);
				item.ImageKey = prototype.ImageKey;
				Point cp = listViewActions.PointToClient(new Point(e.X, e.Y));
				ListViewItem insertAtItem = listViewActions.GetItemAt(cp.X, cp.Y);
				if(insertAtItem == null)
				{
					listViewActions.Items.Add(item);
					eventList[listViewEvents.SelectedItems[0]].Actions.Add(action);
				}
				else
				{
					listViewActions.Items.Insert(insertAtItem.Index, item);
					eventList[listViewEvents.SelectedItems[0]].Actions.Insert(insertAtItem.Index, action);
				}
				
				actionList.Add(item, action);
				action.ShowEditForm();
			}
			else
			{
				//Return if the items are not selected in the ListView control.
				if(listViewActions.SelectedItems.Count==0)
				{
				   return;
				}
				
				//Returns the location of the mouse pointer in the ListView control.
				Point cp = listViewActions.PointToClient(new Point(e.X, e.Y));
				//Obtain the item that is located at the specified location of the mouse pointer.
				ListViewItem dragToItem = listViewActions.GetItemAt(cp.X, cp.Y);
				if(dragToItem==null)
				{
				    return;
				} 
				//Obtain the index of the item at the mouse pointer.
				int dragIndex = dragToItem.Index;
				ListViewItem[] sel=new ListViewItem [listViewActions.SelectedItems.Count];
				for(int i=0; i<=listViewActions.SelectedItems.Count-1;i++)
				{
				     sel[i]=listViewActions.SelectedItems[i];
				}
				for(int i=0; i<sel.GetLength(0);i++)
				{ 
					//Obtain the ListViewItem to be dragged to the target location.
					ListViewItem dragItem = sel[i];
					int itemIndex = dragIndex;
					if(itemIndex==dragItem.Index)
					{
						return;
					}
					if(dragItem.Index<itemIndex)
						itemIndex++;
					else
						itemIndex=dragIndex+i;
					
					//Removes the item from the initial location while 
					//the item is moved to the new location.
					int oldIndex = dragItem.Index;
					if(dragIndex > oldIndex)
						itemIndex--;
					listViewActions.Items.Remove(dragItem);
					//Insert the item at the mouse pointer.
					listViewActions.Items.Insert(itemIndex, dragItem);
				  
				}
				Event evt = eventList[listViewEvents.SelectedItems[0]];
				evt.Actions.Clear();
				foreach(ListViewItem item in listViewActions.Items)
				{
					evt.Actions.Add(actionList[item]);
				}
			}
		}
		
		void ListViewActionSetItemDrag(object sender, ItemDragEventArgs e)
		{
			ListView listView = sender as ListView;
			listView.DoDragDrop(listView.SelectedItems[0] as ListViewItem, DragDropEffects.Copy);
		}
		
		void ListViewEventsSelectedIndexChanged(object sender, EventArgs e)
		{
			listViewActions.Items.Clear();
			if(listViewEvents.SelectedItems.Count == 0)
				return;
			
			Event selectedEvent = eventList[listViewEvents.SelectedItems[0]];
			foreach(Action act in selectedEvent.Actions)
			{
				ListViewItem item = new ListViewItem(act.Description);
				item.ImageKey = act.Prototype.ImageKey;
				actionList.Add(item, act);
				listViewActions.Items.Add(item);
			}
		}
		
		void ListViewActionsMouseDoubleClick(object sender, MouseEventArgs e)
		{
			if(listViewActions.SelectedItems.Count == 0)
				return;
			
			Action action = actionList[listViewActions.SelectedItems[0]];
			action.ShowEditForm();
		}
		
		void ButtonChooseSpriteClick(object sender, EventArgs e)
		{
			throw new NotImplementedException();
		}
		
		void ButtonSpriteNewClick(object sender, EventArgs e)
		{
			throw new NotImplementedException();
		}
		
		void ButtonSpriteEditClick(object sender, EventArgs e)
		{
			throw new NotImplementedException();
		}
	}
}
